@echo off
REM batDocker.cmd
REM Purpose: parse config.txt and expose variables for the Docker helper script.
REM This file implements task 4: read config.txt, remove surrounding quotes,
REM provide sensible defaults, and print the parsed values.

REM -----------------------------------------------------------------------------
REM Usage & quick reference (also in README.md)
REM -----------------------------------------------------------------------------
REM Requirements:
REM  - Windows with Docker Desktop installed and `docker` available on PATH.
REM  - `config.txt` next to this script containing at least ImageName and ImageVersion.
REM
REM Quick examples (PowerShell / pwsh):
REM   # Build image
REM   pwsh -c ".\batDocker.cmd build"
REM
REM   # Start (create if missing), then attach interactive shell
REM   pwsh -c ".\batDocker.cmd start"
REM
REM   # Stop
REM   pwsh -c ".\batDocker.cmd stop"
REM
REM   # Remove (will stop first if running)
REM   pwsh -c ".\batDocker.cmd remove"
REM
REM Notes:
REM  - The script names containers as ImageName_ImageVersion_%USERNAME%_<cwd_folder>.
REM  - Default mounts: current directory -> /home/shawn/work, %USERPROFILE%\.ssh -> /home/shawn/.ssh (read-only).
REM  - If you need more advanced path handling, consider using a PowerShell variant (psDocker.ps1) which is not included.
REM -----------------------------------------------------------------------------

SETLOCAL ENABLEDELAYEDEXPANSION

rem Determine config file located in the same directory as this script,
rem even if the script is executed from a different current directory.
set "SCRIPT_DIR=%~dp0"
set "CONFIG_FILE=%SCRIPT_DIR%config.txt"
if not exist "%CONFIG_FILE%" (
    echo Config file '%CONFIG_FILE%' not found.
    EXIT /B 1
)

rem --- sensible defaults ---
set "ImageName=win_docker"
set "ImageVersion=latest"
set "UserName=%USERNAME%"
for %%I in ("%CD%") do set "FolderName=%%~nI"

rem --- read values from config.txt if present ---
rem Use findstr to locate lines starting with the key name and grab the RHS
for /f "usebackq tokens=2 delims==" %%v in (`findstr /B /C:"ImageName=" "%CONFIG_FILE%" 2^>nul`) do (
    set "ImageName=%%~v"
)
for /f "usebackq tokens=2 delims==" %%v in (`findstr /B /C:"ImageVersion=" "%CONFIG_FILE%" 2^>nul`) do (
    set "ImageVersion=%%~v"
)
for /f "usebackq tokens=2 delims==" %%v in (`findstr /B /C:"UserName=" "%CONFIG_FILE%" 2^>nul`) do (
    set "UserName=%%~v"
)
for /f "usebackq tokens=2 delims==" %%v in (`findstr /B /C:"FolderName=" "%CONFIG_FILE%" 2^>nul`) do (
    set "FolderName=%%~v"
)

rem --- strip surrounding quotes from parsed values ---
set "ImageName=%ImageName:"=%"
set "ImageVersion=%ImageVersion:"=%"
set "UserName=%UserName:"=%"
set "FolderName=%FolderName:"=%"

rem --- build convenient names ---
set "FULL_IMAGE_TAG=%ImageName%:%ImageVersion%"
set "FULL_IMAGE_NAME=%ImageName%_%ImageVersion%"
set "CONTAINER_NAME=%FULL_IMAGE_NAME%_%UserName%_%FolderName%"

set "COMMAND=%~1"
rem Only display parsed configuration when no command was provided
if "%COMMAND%"=="" (
    echo Parsed configuration from '%CONFIG_FILE%':
    echo   ImageName=%ImageName%
    echo   ImageVersion=%ImageVersion%
    echo   FULL_IMAGE_TAG=%FULL_IMAGE_TAG%
    echo   FULL_IMAGE_NAME=%FULL_IMAGE_NAME%
    echo   CONTAINER_NAME=%CONTAINER_NAME%
    echo.
    echo Usage: %~n0 ^<command^>
    echo   commands: build ^| start ^| stop ^| remove
    EXIT /B 1
)

if /I "%COMMAND%"=="build" (
    echo Preparing to build image '%FULL_IMAGE_TAG%'

    rem Try to detect host UID/GID via WSL if available; otherwise default to 1000
    set "HOST_UID=1000"
    set "HOST_GID=1000"
    echo Using build args: HOST_UID=!HOST_UID! HOST_GID=!HOST_GID!

    rem Check if image already exists
    docker image inspect "%FULL_IMAGE_TAG%" >nul 2>&1
    if !ERRORLEVEL! equ 0 (
        echo Docker image '%FULL_IMAGE_TAG%' already exists. Skipping build.
        EXIT /B 0
    )

    echo Building Docker image '%FULL_IMAGE_TAG%'...
    docker build --build-arg HOST_UID=!HOST_UID! --build-arg HOST_GID=!HOST_GID! -t "%FULL_IMAGE_TAG%" .
    if %ERRORLEVEL% neq 0 (
        echo Docker build failed with exit code %ERRORLEVEL% >&2
        EXIT /B %ERRORLEVEL%
    )
    echo Docker image '%FULL_IMAGE_TAG%' built successfully.
    EXIT /B 0
)

if /I "%COMMAND%"=="stop" (
    echo Preparing to stop container '%CONTAINER_NAME%'

    rem Check if the container is currently running
    docker ps --filter "name=%CONTAINER_NAME%" --filter "status=running" --format "{{.Names}}" | findstr /I "^%CONTAINER_NAME%$" >nul
    if %ERRORLEVEL%==0 (
        echo Stopping running container '%CONTAINER_NAME%'...
        docker stop "%CONTAINER_NAME%"
        if %ERRORLEVEL% neq 0 (
            echo Docker stop failed with exit code %ERRORLEVEL% >&2
            EXIT /B %ERRORLEVEL%
        )
        echo Docker container '%CONTAINER_NAME%' stopped successfully.
        EXIT /B 0
    )
)

if /I "%COMMAND%"=="start" (
    rem Ensure image exists
    docker image inspect "%FULL_IMAGE_TAG%" >nul 2>&1
    if %ERRORLEVEL% neq 0 (
        echo Docker image '%FULL_IMAGE_TAG%' not found. Run: %~n0 build
        EXIT /B 3
    )

    rem Check if container exists (robust check that avoids ERRORLEVEL parse-time issues)
    set "CONTAINER_FOUND="
    for /f "usebackq delims=" %%N in (`docker container ls -a --filter "name=%CONTAINER_NAME%" --format "{{.Names}}" 2^>nul`) do (
        if /I "%%~N"=="%CONTAINER_NAME%" set "CONTAINER_FOUND=1"
    )
    if not defined CONTAINER_FOUND (
        echo Container '%CONTAINER_NAME%' does not exist. Creating...
        rem Use the current working directory (where the command was run), not the script directory
        set "WORK_HOST=!CD!"
        rem Prepare mounts (convert Windows path to docker-friendly path)
        call :win_to_docker "!CD!"
        set "DOCKER_WORK=!DOCKER_OUT!"

        rem Create container detached with a keepalive process so it survives shell exit
        docker run -d -v "!DOCKER_WORK!:/home/shawn/work" --name "%CONTAINER_NAME%" "%FULL_IMAGE_TAG%" tail -f /dev/null
        if !ERRORLEVEL! neq 0 (
            echo Failed to create container '%CONTAINER_NAME%' >&2
            EXIT /B !ERRORLEVEL!
        )
        set "CONTAINER_FOUND=1"
    ) else (
        echo Container '%CONTAINER_NAME%' already exists.
    )

    rem If container is not running, start it
    docker ps --filter "name=%CONTAINER_NAME%" --filter "status=running" --format "{{.Names}}" | findstr /I "^%CONTAINER_NAME%$" >nul
    if !ERRORLEVEL! neq 0 (
        echo Starting container '%CONTAINER_NAME%'...
        docker start "%CONTAINER_NAME%"
        if !ERRORLEVEL! neq 0 (
            echo Failed to start container '%CONTAINER_NAME%' >&2
            EXIT /B !ERRORLEVEL!
        )
    ) else (
        echo Container '%CONTAINER_NAME%' is already running.
    )

    rem Attach an interactive shell (delegated to a subroutine to avoid parser issues)
    call :attach_container "%CONTAINER_NAME%"
    EXIT /B !ERRORLEVEL!
)

if /I "%COMMAND%"=="remove" (
    echo Preparing to remove container '%CONTAINER_NAME%'

    rem Check if the container exists at all
    docker ps -a --filter "name=%CONTAINER_NAME%" --format "{{.Names}}" | findstr /I "^%CONTAINER_NAME%$" >nul
    if %ERRORLEVEL% neq 0 (
        echo Docker container '%CONTAINER_NAME%' does not exist. Nothing to remove.
        EXIT /B 0
    )

    rem If running, stop it first
    docker ps --filter "name=%CONTAINER_NAME%" --filter "status=running" --format "{{.Names}}" | findstr /I "^%CONTAINER_NAME%$" >nul
    if %ERRORLEVEL%==0 (
        echo Stopping running container '%CONTAINER_NAME%' before removal...
        docker stop "%CONTAINER_NAME%"
        if %ERRORLEVEL% neq 0 (
            echo Docker stop failed with exit code %ERRORLEVEL% >&2
            EXIT /B %ERRORLEVEL%
        )
    )

    echo Removing Docker container '%CONTAINER_NAME%'...
    docker rm "%CONTAINER_NAME%"
    if %ERRORLEVEL% neq 0 (
        echo Docker remove failed with exit code %ERRORLEVEL% >&2
        EXIT /B %ERRORLEVEL%
    )
    echo Docker container '%CONTAINER_NAME%' removed successfully.
    EXIT /B 0
)

rem Unknown or unimplemented command
echo Unknown command '%COMMAND%'. Supported: build, start, stop, remove
EXIT /B 2

:attach_container
rem %1 = container name
set "TARGET_NAME=%~1"
set "CONTAINER_ID="
rem Find running container ID with exact name match
for /f "usebackq tokens=1* delims=|" %%I in (`docker ps --filter "name=%TARGET_NAME%" --filter "status=running" --format "{{.ID}}|{{.Names}}" 2^>nul`) do (
    if /I "%%~J"=="%TARGET_NAME%" set "CONTAINER_ID=%%~I"
)
if "%CONTAINER_ID%"=="" (
    echo Could not determine running container ID for '%TARGET_NAME%'. Aborting attach.
    EXIT /B 4
)
rem Exec into the container by ID
docker exec -it "%CONTAINER_ID%" /bin/bash
EXIT /B %ERRORLEVEL%

:win_to_docker
rem Convert a Windows path to a docker-friendly path (best-effort).
rem Input: %1 (Windows path, may be quoted). Output: DOCKER_OUT (no surrounding quotes).
setlocal ENABLEDELAYEDEXPANSION
set "_p=%~1"
rem strip trailing backslash
if defined _p if "%_p:~-1%"=="\" set "_p=%_p:~0,-1%"

rem If looks like drive letter (C:\...), convert to //C/... with forward slashes
if not "%_p:~1,1%"==":" goto :_unc_or_other
set "_drive=%_p:~0,1%"
set "_rest=%_p:~2%"
set "_rest=%_rest:\=/%"
rem ensure leading slash on rest
if not "%_rest:~0,1%"=="/" set "_rest=/!_rest!"
endlocal & set "DOCKER_OUT=//%_drive%%_rest%"
EXIT /B 0

:_unc_or_other
rem UNC or other path: replace backslashes with forward slashes
set "_p=%_p:\=/%"
endlocal & set "DOCKER_OUT=%_p%"
EXIT /B 0
